package com.download.manager;

import android.os.Environment;

import com.download.manager.beans.LoadTaskBean;
import com.download.manager.interfaces.OnDownLoadTaskCallBack;
import com.download.manager.interfaces.OnSingleFileLoadCallBack;
import com.download.manager.utils.M3u8FileUtil;

import java.io.File;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
public class M3u8DownLoadManager {

    private static M3u8DownLoadManager manager;

    private M3u8DownLoadManager(){
        try {
            //屏蔽媒体扫描
            File file = new File(SAVE_DIRS);
            if (!file.exists()) {
                file.mkdirs();
            }
            File m = new File(SAVE_DIRS, ".nomedia");
            if (!file.exists()) {
                m.createNewFile();
            }
        }catch (Exception e){
            e.printStackTrace();
        }
    }

    public synchronized static M3u8DownLoadManager getInstance(){
        if(manager==null){
            manager=new M3u8DownLoadManager();
        }
        return manager;
    }

    public M3u8DownLoadManager setSaveDirs(String saveDirs) {
        if(saveDirs.startsWith("/")){
            this.SAVE_DIRS = rootPath+saveDirs;
        }else {
            this.SAVE_DIRS = rootPath+"/"+saveDirs;
        }
        return this;
    }

    public M3u8DownLoadManager setMaxTaskSize(int maxTaskSize) {
        this.maxTaskSize = maxTaskSize;
        return this;
    }

    //sd卡根目录
    private String rootPath= Environment.getExternalStorageDirectory().getPath();
    //m3u8本地保存文件目录名
    public String SAVE_DIRS=rootPath+"/videoCache";
    //用于播放本地m3u8的缓存文件启示命名
    public final String CACHE_FILE_HEADER="#_cache_";
    //同时最大的下载任务数
    public int maxTaskSize=3;

    //等待下载的url列表
    public List<LoadTaskBean> loadUrlList=new ArrayList<>();
    //等待下载的map
    public Map<String, LoadTaskBean> loadUrlMap=new HashMap<>();
    //正在下载的map
    public Map<String,LoadTaskBean> loadTaskMap=new HashMap<>();
    //下载信息回调监听
    private Map<String, OnDownLoadTaskCallBack> loadTaskCallBackMap=new HashMap<>();
    //单个文件下载的进度回调监听
    private Map<String, OnSingleFileLoadCallBack> singleFileLoadCallBackMap=new HashMap<>();

    /**
     * 开启下载任务
     * 此时将此任务加入待下载列表
     * @param url 下载的链接
     * @return 返回的数据提示
     */
    public String startDownLoadUrl(String url){
        if(loadUrlMap.get(url)!=null || loadTaskMap.get(url)!=null){
            //该下载链接已在待下载列表或者正在下载
            return "已在缓存列表中";
        }
        LoadTaskBean bean=new LoadTaskBean().initTaskBean(url);
        //未达最大下载数直接加入下载任务列表
        if(loadTaskMap.size()<maxTaskSize){
            bean.startTask();
            loadTaskMap.put(bean.url,bean);
        }else {
            loadUrlList.add(bean);
            loadUrlMap.put(url, bean);
        }
        return "已加入缓存列表";
    }

    /**
     * 开启新的下载任务
     * @param position 待加载列表需要下载的序号
     * @param toMaxSize 是否循环加载到最多任务数
     */
    public void startNewTask(int position,boolean toMaxSize){
        if(loadUrlList.size()>0 && loadTaskMap.size()<maxTaskSize){
            LoadTaskBean bean=loadUrlList.get(position);
            bean.startTask();
            loadUrlList.remove(position);
            loadUrlMap.remove(bean.url);
            loadTaskMap.put(bean.url,bean);
            if(toMaxSize) {
                //循坏加载项任务,直到加载最大任务数，或者待下载列表空
                startNewTask(0,true);
            }
        }else {
            //已达最大下载数 或者 无带下载项目
        }
    }

    /**
     * 暂停或者终止任务
     * @param url
     */
    public void pauseOrStopTask(String url){
        LoadTaskBean bean=null;
        if(loadUrlMap.get(url)!=null){
            bean=loadUrlMap.get(url);
            loadUrlMap.remove(url);
            if(loadTaskCallBackMap.get(url)!=null){
                loadTaskCallBackMap.get(url).onPauseDownLoad(url,url);
                loadTaskCallBackMap.remove(url);
            }
        }else if(loadTaskMap.get(url)!=null){
            bean=loadTaskMap.get(url);
            loadTaskMap.remove(url);
            bean.stopTask();
        }
        for(int i=0;i<loadUrlList.size();i++){
            if(loadUrlList.get(i).url.equals(url)){
                loadUrlList.remove(i);
                break;
            }
        }
    }

    /**
     * 根据url获取已缓存的下载信息
     * @param url
     * @return
     */
    public LoadTaskBean getLoadUrlInfo(String url){
        if(loadUrlMap.get(url)!=null){
            return loadUrlMap.get(url);
        }else if(loadTaskMap.get(url)!=null){
            return loadTaskMap.get(url);
        }else {
            return null;
        }
    }

    public void clearTaskMap(){
        if(!loadUrlMap.isEmpty()){
            loadUrlMap.clear();
        }
        if(!loadTaskMap.isEmpty()) {
            for (Map.Entry<String, LoadTaskBean> helps : loadTaskMap.entrySet()) {
                helps.getValue().stopTask();
            }
            loadTaskMap.clear();
        }
        if(!loadTaskCallBackMap.isEmpty()){
            loadTaskCallBackMap.clear();
        }
        if(!singleFileLoadCallBackMap.isEmpty()){
            singleFileLoadCallBackMap.clear();
        }
    }

    public void clearCache(){
        M3u8FileUtil.deleteFile(new File(SAVE_DIRS));
    }

    /**
     * 当一个任务结束之后，开启下一个待下载任务
     * @param url
     */
    public void refreshLoadTask(String url){
        //移除已完成的任务
        loadTaskMap.remove(url);
        //防止最大下载任务数变化，此处强制下载任务数遍历到最大
        M3u8DownLoadManager.getInstance().startNewTask(0,true);
    }

    public void setDownLoadTaskCallBack(String url,OnDownLoadTaskCallBack callBack){
        loadTaskCallBackMap.put(url,callBack);
    }

    public OnDownLoadTaskCallBack getDownLoadTaskCallBack(String url){
        return loadTaskCallBackMap.get(url);
    }

    public void removeDownLoadTaskCallBack(String url){
        loadTaskCallBackMap.remove(url);
    }

    public void clearDownLoadTaskCallBack(){
        loadTaskCallBackMap.clear();
    }

    public void setSingleFileLoadCallBack(String url,OnSingleFileLoadCallBack callBack){
        singleFileLoadCallBackMap.put(url,callBack);
    }

    public OnSingleFileLoadCallBack getSingleFileLoadCallBack(String url){
        return singleFileLoadCallBackMap.get(url);
    }

    public void removeSingleFileLoadCallBack(String url){
        singleFileLoadCallBackMap.remove(url);
    }

    public void clearSingleFileLoadCallBack(){
        singleFileLoadCallBackMap.clear();
    }
}
